package com.jf.cloud.group.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.jf.cloud.api.feign.SearchOrderFeignClient;
import com.jf.cloud.api.leaf.dto.SegmentDTO;
import com.jf.cloud.api.leaf.dto.SegmentItemDTO;
import com.jf.cloud.api.leaf.feign.SegmentFeignClient;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.api.order.vo.GroupInfoVO;
import com.jf.cloud.api.user.feign.UserFeignClient;
import com.jf.cloud.api.user.vo.UserApiVO;
import com.jf.cloud.common.cache.constant.GroupCacheNames;
import com.jf.cloud.common.cache.util.CacheManagerUtil;
import com.jf.cloud.common.constant.Constant;
import com.jf.cloud.common.constant.DistributedIdKey;
import com.jf.cloud.common.constant.SendTypeEnum;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.bo.OrderIdWithRefundIdBO;
import com.jf.cloud.common.order.bo.PayNotifyBO;
import com.jf.cloud.common.order.vo.OrderActivityVO;
import com.jf.cloud.common.order.vo.SendNotifyBO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.rocketmq.config.RocketMqConstant;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.group.bo.GroupOrderBO;
import com.jf.cloud.group.bo.SuccessGroupOrderBO;
import com.jf.cloud.group.constant.GroupOrderStatusEnum;
import com.jf.cloud.group.constant.TeamStatusEnum;
import com.jf.cloud.group.mapper.GroupActivityMapper;
import com.jf.cloud.group.mapper.GroupOrderMapper;
import com.jf.cloud.group.mapper.GroupTeamMapper;
import com.jf.cloud.group.model.GroupOrder;
import com.jf.cloud.group.model.GroupTeam;
import com.jf.cloud.group.service.GroupOrderService;
import com.jf.cloud.group.vo.GroupActivityVO;
import com.jf.cloud.group.vo.GroupOrderVO;
import com.jf.cloud.group.vo.GroupTeamVO;
import com.jf.cloud.group.vo.app.AppGroupUserVO;
import ma.glasnost.orika.MapperFacade;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 拼团订单表
 *
 * @author YXF
 * @date 2021-03-20 10:39:32
 */
@Service
public class GroupOrderServiceImpl implements GroupOrderService {

    private static final Logger log = LoggerFactory.getLogger(GroupOrderServiceImpl.class);

    @Autowired
    private GroupOrderMapper groupOrderMapper;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private GroupTeamMapper groupTeamMapper;

    @Autowired
    private GroupActivityMapper groupActivityMapper;

    @Autowired
    private CacheManagerUtil cacheManagerUtil;

    @Autowired
    private RocketMQTemplate groupOrderSuccessTemplate;
    @Autowired
    private RocketMQTemplate groupOrderUnSuccessTemplate;
    @Autowired
    private RocketMQTemplate sendGroupNotifyToUserTemplate;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private RocketMQTemplate groupOrderUnSuccessRefundTemplate;
    @Autowired
    private SegmentFeignClient segmentFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;
    @Autowired
    private SearchOrderFeignClient searchOrderFeignClient;

    @Override
    public void update(GroupOrder groupOrder) {
        groupOrderMapper.update(groupOrder);
    }

    @Override
    public void deleteById(Long groupOrderId) {
        groupOrderMapper.deleteById(groupOrderId);
    }

    @Override
    public GroupOrderVO getByOrderId(Long orderId) {
        ServerResponseEntity<OrderActivityVO> serverResponseEntity = orderFeignClient.getActivityOrderInfo(orderId);
        if (serverResponseEntity.isFail()) {
            throw new LuckException(serverResponseEntity.getMsg());
        }
        Long activityId = serverResponseEntity.getData().getActivityId();
        return groupOrderMapper.getByOrderId(orderId, activityId);
    }

    @Override
    public List<AppGroupUserVO> listApiGroupUserDto(Long groupTeamId) {
        List<AppGroupUserVO> appGroupUserList = groupOrderMapper.listApiGroupUserDto(groupTeamId);
        if (CollUtil.isEmpty(appGroupUserList)) {
            return null;
        }
        Set<Long> userIds = appGroupUserList.stream().map(AppGroupUserVO::getUserId).collect(Collectors.toSet());
        ServerResponseEntity<List<UserApiVO>> userResponse = userFeignClient.getUserByUserIds(new ArrayList<>(userIds));
        List<UserApiVO> data = userResponse.getData();
        Map<Long, UserApiVO> userMap = data.stream().collect(Collectors.toMap(UserApiVO::getUserId, u -> u));
        for (AppGroupUserVO groupUserVO : appGroupUserList) {
            // 机器人参团
            if (Objects.isNull(groupUserVO.getUserId()) || Objects.equals(groupUserVO.getUserId(), 0L)) {
                groupUserVO.setNickName(Constant.GROUP_SYSTEM_USER);
            } else {
                UserApiVO userApiVO = userMap.get(groupUserVO.getUserId());
                groupUserVO.setNickName(userApiVO.getNickName());
                groupUserVO.setPic(userApiVO.getPic());
            }
        }
        return appGroupUserList;
    }

    @Override
    public GroupOrderVO getUserGroupOrderByGroupTeamId(Long groupTeamId) {
        return groupOrderMapper.getUserGroupOrderByGroupTeamId(groupTeamId, AuthUserContext.get().getUserId());
    }

    @Override
    public Integer getUserHadSpuCountByGroupActivityId(Long userId, Long groupActivityId) {
        List<Long> orderIds = groupOrderMapper.getUserHadSpuCountByGroupActivityId(userId, groupActivityId);
        ServerResponseEntity<Integer> orderResponse = orderFeignClient.countNormalOrderByOrderIds(orderIds);
        if (!orderResponse.isSuccess()) {
            throw new LuckException(orderResponse.getMsg());
        }
        return orderResponse.getData();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(GroupOrderBO groupOrderBO) {
        // 插入拼团订单
        GroupOrder groupOrder = new GroupOrder();
        // 获取分布式id
        List<SegmentItemDTO> segmentItemList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_GROUP_ORDER, 1));
        if (Objects.equals(groupOrderBO.getGroupTeamId(), 0L)) {
            segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_GROUP_TEAM, 1));
        }
        // 获取团购订单id及团购队伍id列表
        ServerResponseEntity<Map<String, List<Long>>> segmentIdResponse = segmentFeignClient.batchSegmentIdWithDateTime(new SegmentDTO(groupOrderBO.getGroupActivityId(), segmentItemList));
        if (segmentIdResponse.isFail()) {
            throw new LuckException(segmentIdResponse.getMsg());
        }
        Map<String, List<Long>> idMap = segmentIdResponse.getData();
        // 如果为团长，则需新建拼团团队
        if (Objects.equals(groupOrderBO.getGroupTeamId(), 0L)) {
            GroupTeam groupTeam = new GroupTeam();
            groupTeam.setGroupTeamId(idMap.get(DistributedIdKey.MALL4CLOUD_GROUP_TEAM).get(0));
            groupTeam.setShareUserId(groupOrderBO.getShareUserId());
            groupTeam.setGroupSpuId(groupOrderBO.getSpuId());
            groupTeam.setGroupActivityId(groupOrderBO.getGroupActivityId());
            groupTeam.setJoinNum(1);
            groupTeam.setShopId(groupOrderBO.getShopId());
            groupTeam.setStatus(TeamStatusEnum.WAITING_GROUP.value());
            groupTeam.setTotalPrice(groupOrder.getPayPrice());
            groupTeamMapper.save(groupTeam);
            groupOrder.setGroupTeamId(groupTeam.getGroupTeamId());
        } else {
            groupOrder.setGroupTeamId(groupOrderBO.getGroupTeamId());
        }

        groupOrder.setGroupOrderId(idMap.get(DistributedIdKey.MALL4CLOUD_GROUP_ORDER).get(0));
        groupOrder.setGroupActivityId(groupOrderBO.getGroupActivityId());
        groupOrder.setUserId(groupOrderBO.getUserId());
        groupOrder.setOrderId(groupOrderBO.getOrderId());
        groupOrder.setActivityProdPrice(groupOrderBO.getActivityProdPrice());
        groupOrder.setPayPrice(groupOrderBO.getPayPrice());
        groupOrder.setShopId(groupOrderBO.getShopId());
        groupOrder.setIdentityType(Objects.equals(groupOrderBO.getGroupTeamId(), 0L) ? 1 : 0);
        groupOrder.setStatus(GroupOrderStatusEnum.WAITING_PAY.value());
        groupOrder.setCount(groupOrderBO.getCount());
        groupOrderMapper.save(groupOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelGroupOrder(List<Long> orderIds) {
        GroupOrderVO groupOrder = getByOrderId(orderIds.get(0));
        if (!Objects.equals(groupOrder.getStatus(), GroupOrderStatusEnum.WAITING_PAY.value())) {
            return;
        }

        for (Long orderId : orderIds) {
            groupOrderMapper.cancelGroupOrder(orderId, groupOrder.getGroupActivityId());
        }
        groupTeamMapper.cancelGroupTeam(groupOrder.getGroupTeamId());
        //TODO 取消团购订单算取消拼团？
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payNotifyGroupOrder(PayNotifyBO message) {
        Long orderId = message.getOrderIds().get(0);
        // 获取用户拼团订单信息
        GroupOrderVO groupOrder = getByOrderId(orderId);
        if (Objects.equals(groupOrder.getStatus(), GroupOrderStatusEnum.SUCCESS.value())) {
            return;
        }
        // 如果为团长则直接开团，否则判断是否拼团已满
        if (Objects.equals(groupOrder.getIdentityType(), 1)) {
            // 开团
            openGroup(orderId, groupOrder);
        } else {
            // 获取拼团团队订单
            GroupTeamVO groupTeam = groupTeamMapper.getByGroupTeamId(groupOrder.getGroupTeamId());
            // 如果团已满，或回调的时候团已经失败了（之前的团退款了）则开新团
            // 否则加入该团
            if (Objects.equals(groupTeam.getStatus(), TeamStatusEnum.SUCCESS.value())
                    || Objects.equals(groupTeam.getStatus(), TeamStatusEnum.FAIL.value())) {
                // 开新团
                openNewGroup(orderId, groupOrder, groupTeam);
            } else if (Objects.equals(groupTeam.getStatus(), TeamStatusEnum.IN_GROUP.value())) {
                // 参团
                joinGroup(orderId, groupOrder, groupTeam);
            }
        }
    }

    @Override
    public void unSuccess(Long groupTeamId) {
        log.info("开始退款=====================》"+groupTeamId);
        Date nowDate = new Date();
        // 机器人列表
        List<GroupOrder> robot = new ArrayList<>(Constant.INITIAL_CAPACITY);
        GroupTeamVO groupTeam = groupTeamMapper.getByGroupTeamId(groupTeamId);
        if (!Objects.equals(groupTeam.getStatus(), TeamStatusEnum.IN_GROUP.value())) {
            return;
        }
        GroupActivityVO groupActivity = groupActivityMapper.getByGroupActivityId(groupTeam.getGroupActivityId());

        List<SuccessGroupOrderBO> successGroupOrders = groupOrderMapper.listSuccessOrderIdByTeamId(groupTeam.getGroupTeamId());
        log.info("订单数量=====================》"+successGroupOrders.size());
        if (CollectionUtil.isEmpty(successGroupOrders)) {
            return;
        }
        List<Long> orderIds = successGroupOrders.stream().map(SuccessGroupOrderBO::getOrderId).collect(Collectors.toList());

        // 如果未成团，有机器人可以成团，不需要进行退款的操作
        if (groupActivity.getHasRobot() == 1) {
            addRobot(nowDate, robot, groupTeam, groupActivity, orderIds);
        }

        List<OrderIdWithRefundIdBO> orderIdWithRefundIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (SuccessGroupOrderBO successGroupOrder : successGroupOrders) {
            ServerResponseEntity<Long> segmentId = segmentFeignClient.getSegmentIdWithDateTime(DistributedIdKey.MALL4CLOUD_REFUND, successGroupOrder.getUserId());

            OrderIdWithRefundIdBO orderIdWithRefundIdBO = new OrderIdWithRefundIdBO();
            orderIdWithRefundIdBO.setOrderId(successGroupOrder.getOrderId());
            orderIdWithRefundIdBO.setRefundId(segmentId.getData());
            orderIdWithRefundIdBO.setShopId(successGroupOrder.getShopId());
            orderIdWithRefundIds.add(orderIdWithRefundIdBO);
        }

        log.info("退款数量=====================》"+orderIdWithRefundIds.size());
        // 发送退款服务进行退款的通知

        TransactionSendResult transactionSendResult = groupOrderUnSuccessRefundTemplate.sendMessageInTransaction(RocketMqConstant.GROUP_ORDER_UN_SUCCESS_REFUND_TOPIC, new GenericMessage<>(orderIdWithRefundIds), groupTeamId);

        log.info("发送完退款数量=====================》"+orderIdWithRefundIds.size());
        if (!Objects.equals(transactionSendResult.getLocalTransactionState(), LocalTransactionState.COMMIT_MESSAGE)) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }

        // 消息推送-拼团失败
        for (Long orderId : orderIds) {
            SendNotifyBO sendNotifyBO = new SendNotifyBO();
            sendNotifyBO.setSendType(SendTypeEnum.GROUP_FAIL.getValue());
            sendNotifyBO.setBizId(orderId);
            SendStatus sendBizStatus = sendGroupNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_GROUP_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyBO)).getSendStatus();
        }

    }

    /**
     * 如果未成团，有机器人可以成团，则添加机器人
     *
     * @param nowDate       当前时间
     * @param robot         机器人列表
     * @param groupTeam     拼团队伍
     * @param groupActivity 团购活动
     * @param orderIds      订单id列表
     */
    private void addRobot(Date nowDate, List<GroupOrder> robot, GroupTeamVO groupTeam, GroupActivityVO groupActivity, List<Long> orderIds) {

        // 模拟参团操作（添加机器人）
        for (int i = 0; i < groupActivity.getGroupNumber() - groupTeam.getJoinNum(); i++) {
            GroupOrder groupOrder = new GroupOrder();
            groupOrder.setShopId(groupTeam.getShopId());
            groupOrder.setGroupTeamId(groupTeam.getGroupTeamId());
            groupOrder.setGroupActivityId(groupActivity.getGroupActivityId());
            groupOrder.setUserId(0L);
            groupOrder.setIdentityType(0);
            groupOrder.setStatus(GroupOrderStatusEnum.SUCCESS.value());
            groupOrder.setCreateTime(nowDate);
            robot.add(groupOrder);
        }
        if (CollectionUtil.isNotEmpty(robot)) {
            // 获取订单id列表
            ServerResponseEntity<Map<String, List<Long>>> segmentIdResponse = segmentFeignClient.batchSegmentIdWithDateTime(new SegmentDTO(groupTeam.getGroupActivityId(), DistributedIdKey.MALL4CLOUD_GROUP_ORDER));
            if (segmentIdResponse.isFail()) {
                throw new LuckException(segmentIdResponse.getMsg());
            }
            List<Long> ids = segmentIdResponse.getData().get(DistributedIdKey.MALL4CLOUD_GROUP_ORDER);
            for (GroupOrder groupOrder : robot) {
                groupOrder.setGroupOrderId(ids.remove(0));
                groupOrderMapper.save(groupOrder);
            }
        }

        int updateStatus = groupTeamMapper.updateToSuccess(mapperFacade.map(groupTeam, GroupTeam.class));
        if (updateStatus < 1) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }

        // 更新已成团人数
        updateGroupOrderInfo(groupActivity.getGroupActivityId());

        // 发送通知给订单，将订单状态变为待发货
        SendStatus groupSendStatus = groupOrderSuccessTemplate.syncSend(RocketMqConstant.GROUP_ORDER_SUCCESS_TOPIC, new GenericMessage<>(orderIds)).getSendStatus();
        if (!Objects.equals(groupSendStatus, SendStatus.SEND_OK)) {
            // 消息发不出去就抛异常，发的出去无所谓
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
        for (Long orderId : orderIds) {
            // 消息推送-拼团成功
            SendNotifyBO sendNotifyBO = new SendNotifyBO();
            sendNotifyBO.setSendType(SendTypeEnum.GROUP_SUCCESS.getValue());
            sendNotifyBO.setBizId(orderId);
            SendStatus sendBizStatus = sendGroupNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_GROUP_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyBO)).getSendStatus();
        }
    }

    @Override
    public Integer getOrderBySpuIdAndUserId(Long groupActivityId, Long spuId, Long userId) {
        return groupOrderMapper.getOrderBySpuIdAndUserId(groupActivityId, spuId, userId);
    }

    @Override
    public void updateGroupOrderInfo(Long groupActivityId) {
        // mongo数据更新存在一定延迟，导致统计的成团数据不准确，稍微加点延迟等待mongo更新
        try {
            TimeUnit.SECONDS.sleep(1L);
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
        ServerResponseEntity<GroupInfoVO> serverResponse = orderFeignClient.getGroupInfoById(groupActivityId);
        if (!serverResponse.isSuccess()) {
            throw new LuckException(serverResponse.getMsg());
        }
        GroupInfoVO groupInfo = serverResponse.getData();
        if (Objects.nonNull(groupInfo)) {
            groupActivityMapper.updateGroupOrderInfo(groupActivityId, groupInfo.getOrderCount(), groupInfo.getNumberCount());
        }
    }


    private void openGroup(Long orderId, GroupOrderVO groupOrder) {
        Date now = new Date();
        GroupTeam newGroupTeam = new GroupTeam();
        newGroupTeam.setTotalPrice(groupOrder.getPayPrice());
        newGroupTeam.setGroupTeamId(groupOrder.getGroupTeamId());
        newGroupTeam.setStatus(TeamStatusEnum.IN_GROUP.value());
        newGroupTeam.setStartTime(now);
        newGroupTeam.setEndTime(DateUtil.offsetMillisecond(now, RocketMqConstant.CANCEL_TIME_INTERVAL));
        groupTeamMapper.update(newGroupTeam);
        int updateStatus = groupOrderMapper.updateToPaySuccess(orderId, null, null, groupOrder.getGroupActivityId());
        if (updateStatus < 1) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
        updateGroupOrderInfo(groupOrder.getGroupActivityId());
        sendMsg(orderId, groupOrder);
    }

    private void sendMsg(Long orderId, GroupOrderVO groupOrder) {
        // 发送延迟消息
        // 发送消息，如果三十分钟后没有成团，则取消订单进行退款
        SendStatus sendStatus = groupOrderUnSuccessTemplate.syncSend(RocketMqConstant.GROUP_ORDER_UN_SUCCESS_TOPIC, new GenericMessage<>(groupOrder.getGroupTeamId()), RocketMqConstant.TIMEOUT, RocketMqConstant.CANCEL_ORDER_DELAY_LEVEL).getSendStatus();
        if (!Objects.equals(sendStatus, SendStatus.SEND_OK)) {
            // 消息发不出去就抛异常，发的出去无所谓
            throw new LuckException(ResponseEnum.EXCEPTION);
        }

        // 消息推送-开团成功
        SendNotifyBO sendNotifyBO = new SendNotifyBO();
        sendNotifyBO.setSendType(SendTypeEnum.GROUP_START.getValue());
        sendNotifyBO.setBizId(orderId);
        SendStatus sendBizStatus = sendGroupNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_GROUP_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyBO)).getSendStatus();
    }

    private void openNewGroup(Long orderId, GroupOrderVO groupOrder, GroupTeamVO groupTeam) {

        // 获取订单id列表
        ServerResponseEntity<Long> segmentIdResponse = segmentFeignClient.getSegmentIdWithDateTime(DistributedIdKey.MALL4CLOUD_GROUP_TEAM, groupTeam.getGroupActivityId());
        if (segmentIdResponse.isFail()) {
            throw new LuckException(segmentIdResponse.getMsg());
        }
        Date now = new Date();
        // 满员开团
        GroupTeam newGroupTeam = new GroupTeam();
        newGroupTeam.setGroupTeamId(segmentIdResponse.getData());
        newGroupTeam.setJoinNum(1);
        newGroupTeam.setCreateTime(now);
        newGroupTeam.setUpdateTime(now);
        newGroupTeam.setStartTime(now);
        newGroupTeam.setShopId(groupTeam.getShopId());
        newGroupTeam.setTotalPrice(groupOrder.getPayPrice());
        newGroupTeam.setShareUserId(groupOrder.getUserId());
        newGroupTeam.setStatus(TeamStatusEnum.IN_GROUP.value());
        newGroupTeam.setGroupSpuId(groupTeam.getGroupSpuId());
        newGroupTeam.setGroupActivityId(groupTeam.getGroupActivityId());
        newGroupTeam.setEndTime(DateUtil.offsetMillisecond(now, RocketMqConstant.CANCEL_TIME_INTERVAL));
        groupTeamMapper.save(newGroupTeam);
        // 当更新分片字段时，只有当set子句中设置的新值等于where子句中给定的旧值时，才不会抛出异常，其他更新分片字段的情况都是不允许的!
        // 这里要更新新的团购团队id值，只能通过先删除原来的，再新增一条新的
        // 不能使用原来的groupOrderMapper.updateToPaySuccess;
        GroupOrderVO groupOrderVO = groupOrderMapper.getByOrderId(orderId, groupTeam.getGroupActivityId());
        groupOrderMapper.deleteById(groupOrderVO.getGroupOrderId());
        // 保存至数据库
        GroupOrder newGroupOrder = mapperFacade.map(groupOrderVO, GroupOrder.class);
        groupOrderVO.setGroupTeamId(newGroupTeam.getGroupTeamId());
        // 支付成功
        groupOrderVO.setStatus(1);
        // 团长
        groupOrderVO.setIdentityType(1);
        groupOrderMapper.save(newGroupOrder);
        updateGroupOrderInfo(groupOrder.getGroupActivityId());

        // 发送延迟消息
        // 发送消息，如果三十分钟后没有成团，则取消订单进行退款
        sendMsg(orderId, groupOrder);
    }

    private void joinGroup(Long orderId, GroupOrderVO groupOrder, GroupTeamVO groupTeam) {
        // 拼团活动
        GroupActivityVO groupActivity = groupActivityMapper.getByGroupActivityId(groupTeam.getGroupActivityId());
        GroupTeam newGroupTeam = new GroupTeam();
        newGroupTeam.setGroupTeamId(groupOrder.getGroupTeamId());
        // 参团
        newGroupTeam.setJoinNum(groupTeam.getJoinNum() + 1);
        newGroupTeam.setTotalPrice(groupTeam.getTotalPrice() + groupOrder.getPayPrice());

        int updateStatus = groupOrderMapper.updateToPaySuccess(orderId, null, null, groupOrder.getGroupActivityId());
        if (updateStatus < 1) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
        // 参团人数未满，更新人数，金额
        if (newGroupTeam.getJoinNum() < groupActivity.getGroupNumber()) {
            groupTeamMapper.update(newGroupTeam);
            return;
        }

        int updateTeamStatus = groupTeamMapper.updateToSuccess(newGroupTeam);


        if (updateTeamStatus < 1) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
        updateGroupOrderInfo(groupActivity.getGroupActivityId());
        // 清除缓存-更新了已成团订单数及人数
        cacheManagerUtil.evictCache(GroupCacheNames.GROUP_BY_SPU_KEY, groupActivity.toString());
        // 发送通知给订单，将所有同一个团并且已支付订单的状态变为待发货
        if (newGroupTeam.getJoinNum() >= groupActivity.getGroupNumber()) {
            List<SuccessGroupOrderBO> successGroupOrders = groupOrderMapper.listSuccessOrderIdByTeamId(groupTeam.getGroupTeamId());
            List<Long> orderIds = successGroupOrders.stream().map(SuccessGroupOrderBO::getOrderId).collect(Collectors.toList());
            SendStatus groupSendStatus = groupOrderSuccessTemplate.syncSend(RocketMqConstant.GROUP_ORDER_SUCCESS_TOPIC, new GenericMessage<>(orderIds)).getSendStatus();
            if (!Objects.equals(groupSendStatus, SendStatus.SEND_OK)) {
                // 消息发不出去就抛异常，发的出去无所谓
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
            for (Long id : orderIds) {
                // 消息推送-拼团成功
                SendNotifyBO sendNotifyBO = new SendNotifyBO();
                sendNotifyBO.setSendType(SendTypeEnum.GROUP_SUCCESS.getValue());
                sendNotifyBO.setBizId(id);
                SendStatus sendBizStatus = sendGroupNotifyToUserTemplate.syncSend(RocketMqConstant.SEND_GROUP_NOTIFY_TO_USER_TOPIC, new GenericMessage<>(sendNotifyBO)).getSendStatus();
            }
        }
    }

}
